有 provider,有 store,有 reducer,明星三缺一,現在只缺 action 啦!第一個要定義的 action,就來寫寫選取角色這個動作吧!
在 actions
資料夾底下建一個 index.js
第一步驟先設定 action type
export const ADD_CHARACTER = 'ADD_CHARACTER';
在這個 actions 檔案中,會有一連串的 functions,這些 functions 並不是我們所謂的 action,而是稱為 action creators
,它會負責回傳 actions。 actions 的型態需要是 JavaScript 物件,我們透過 type 屬性可以自定義,把所有相關資料傳到 function 裡。
現在我們要建置第一個 action creator,取名使用駝峰是大小寫 (Camelcase) addCharacterById
export function addCharacterById(id){
}
接下來我們需要定義 action 物件,把 type 這個屬性設定為 character type
,在 ES6 語法中每一個物件都要有一個 key ID,這個 ID 的值會傳到物件裡。所以現在我們的 character reducer 會接收到一個包含 id 的 add character action type。
export function addCharacterById(id){
const action = {
type: ADD_CHARACTER,
id
}
return action;
}
做完 action 之後,我們可以更新 reducer,當它接受到 action 會被觸發。
進到 reducer/index.js
先把 action import 進來
import { ADD_CHARACTER } from '../actions';
因為我要做的角色陣容應用程式,是當使用者選取角色後,該角色會出現在已選取處,在角色選項的地方會消失,因此,現在要寫 case 讓它去讀取被選取的角色,回傳剩下沒被選取的角色。
switch(action.type){
case ADD_CHARACTER;
let characters = state.filter(item => item.id !== action.id );
return characters;
default:
return state;
}
上面程式碼的意思是只要 action.id
(被選取的角色之id)不等於 item.id 就要存進這個陣列中,把已選取的 item.id 移除。
Redux 需要註冊一個回調函數 store.subscribe(listener) 來獲取 State 的更新,然後我們要在listener 裡面調用 setState() 來更新 React 組件。
store.subscribe(() => console.log('store', store.getState()));
現在再用 dispatch 呼叫 action creator,我就選第二個
store.dispatch(addCharacterById(2));
測試結果我們可以看到 dispatch 之後,item.id
等於 2
的 Wonderwoman 已經被移除
建立一個叫 heros
的 reducer,這個 function 是撰寫把選取的角色存到 heros
這個陣列。
function heros(state = [], action){
switch(action.type) {
case ADD_CHARACTER:
let heros = [...state, creatorCharacter(action.id)];
return heros;
default:
return state;
}
}
function createCharacter(id) {
let character = character_json.find(c => c.id === id);
}
現在可以看到 dispatch 後的 item 存到 heros 的陣列了。